using System;
using System.Collections.Generic;

using Impact.Infrastructure;
using Impact.Model.Objects;
using Impact.Model.Service;
using Impact.Views;

using StructureMap;


namespace Impact.Controllers
{
    /// <summary>
    /// Controller for business logic surrounding RSS feeds
    /// </summary>
    public class RssController
    {

        private IImpactHandler handler;

        /// <summary>
        /// constructor
        /// </summary>
        /// <param name="handler">the handler that is creating this controller</param>
        public RssController( IImpactHandler handler )
        {
            this.handler = handler;
        }

        /// <summary>
        /// Retrieve an RssFeed object for the given parameters
        /// </summary>
        /// <param name="channelName">name of the channel(category) to retrieve articles for.
        /// will return all categories if not specified.</param>
        /// <param name="userName">username to retrieve categories for.  not currently supported.</param>
        /// <param name="ipAddress">IP Address of the request</param>
        public RssFeed GetRssFeed( string channelName, string userName, string ipAddress )
        {

            IArticleService articleService = ObjectFactory.GetInstance<IArticleService>();
            ICategoryService categoryService = ObjectFactory.GetInstance<ICategoryService>();
            
            RssFeed feed = new RssFeed();

            ArticleCategoryCollection categories = new ArticleCategoryCollection();
            if ( !string.IsNullOrEmpty( channelName ) )
            {
                ArticleCategory category = categoryService.FetchByKey( channelName );
                if ( ArticleCategory.IsValid( category ) )
                {
                    categories.Add( category );
                }
            }
            else
            {
                ArticleCategoryCollection all = categoryService.FetchAll( true );
                foreach ( ArticleCategory artCat in all )
                {
                    if ( artCat.AllowRss ) categories.Add( artCat );
                }
            }

            // convert each category into a channel
            foreach ( ArticleCategory category in categories )
            {
                RssChannel channel = new RssChannel();
                channel.title = category.Name;
                channel.link = handler.ResolveRelativeUrl( ContentPresenter.FormatUrl( category ) );
                channel.description = category.Description;
                feed.channel.Add( channel );

                // add the items to this channel
                ArticleCollection articles = articleService.FetchByCategory( category.CategoryId, true );
                foreach ( Article article in articles )
                {
                    RssItem item = new RssItem();
                    item.title = article.Title;
                    item.description = article.Body;
                    item.category.Add( category.Name );
                    item.link = handler.ResolveRelativeUrl( ContentPresenter.FormatUrl( article ) );
                    item.pubDate = ( (DateTime)( article.ModifiedOn ?? article.CreatedOn ) ).ToString();
                    item.guid.isPermaLink = "true";
                    item.guid.Value = item.link;

                    item.pingbackServer = handler.ResolveRelativeUrl( "~/!pingback.ashx" );
                    item.pingbackTarget = item.link;
                    item.slashComments = article.Comments.Count.ToString();
                    item.commentsLink = string.Format( "{0}#comments", item.link );

                    channel.item.Add( item );
                }

            }

            AddSubscriber( channelName, userName, ipAddress );

            return feed;

        }


        private static void AddSubscriber( string channelName, string userName, string ipAddress )
        {
            RssSubscriber subscriber = new RssSubscriber();
            subscriber.ChannelName = channelName;
            subscriber.IpAddress = ipAddress;
            subscriber.RequestDate = DateTime.Now;
            subscriber.Username = userName;

            ISubscriberService service = ObjectFactory.GetInstance<ISubscriberService>();
            service.Save( subscriber );

        }


    }
}
